﻿///////////////////////////////////////////////////////////////////////////////
//
// This file is part of the BassDrop project
//   https://code.google.com/p/bass-drop/
//
//
// Creator:	Gergely Krajcsovszki (krajcsovszkig@hotmail.com)
// Date:	2013-12-23 17:15
//
//
// Copyright © 2013-2014. Gergely Krajcsovszki
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BassDrop.Core.Common.Plugins;
using BassDrop.Core.Common.Options;
using BassDrop.Core.Common.Options.Items;
using BassDrop.Core.Common.Services;
using BassDrop.Core.Common.Utilities;
using BassDrop.Core.Common.Localization;

namespace BassDrop.Core.Common.Cloud
{
	/// <summary>
	/// Base class of options for all cloud plugins
	/// </summary>
	public abstract class CloudOptionsSetBase : PluginOptionsSetBase
	{
		private readonly OptionsItemBase m_makeDefaultActionItem;
		private readonly OptionsItemBase m_removeInstanceActionItem;

		/// <summary>
		/// Constructs a new options set
		/// </summary>
		/// <param name="plugin">the plugin whose options these are</param>
		/// <param name="instance">the plugin instance whose options these are or null if they're for the plugin</param>
		protected CloudOptionsSetBase( BassDropPluginBase plugin, CloudConnectionBase instance )
			: base( plugin, instance )
		{
			if ( Instance != null )
			{
				m_makeDefaultActionItem = new ActionOptionsItem(
					MakeDefault,
					Strings.LabelOptionsSetCloudMakeDefault,
					Strings.LabelOptionsSetCloudMakeDefaultDescription );

				m_removeInstanceActionItem = new ActionOptionsItem(
					RemoveInstance,
					Strings.LabelOptionsSetCloudUnlink,
					Strings.LabelOptionsSetCloudUnlinkDescription );

				OptionList.Add( m_makeDefaultActionItem );
				OptionList.Add( m_removeInstanceActionItem );

				Strings.StaticPropertyChanged += Strings_StaticPropertyChanged;
			}
		}

		/// <summary>
		/// Makes this cloud provider the default
		/// </summary>
		/// <returns></returns>
		private Task MakeDefault()
		{
			((CloudConnectionBase) Instance).MakeDefault();

			return ThreadingUtils.CompletedTask();
		}

		/// <summary>
		/// Unlink this cloud account from the application.
		/// </summary>
		/// <returns></returns>
		private Task RemoveInstance()
		{
			if ( ServiceCenter.UserInterface.ShowMessageBox(
						Strings.LabelOptionsSetCloudUnlinkQuestion,
						Strings.LabelOptionsSetCloudUnlink,
						PortableMessageBoxButton.YesNo,
						PortableMessageBoxImage.Question )
							== PortableMessageBoxResult.Yes )
			{
				Instance.PluginDescriptor.RemoveNamedInstance( Instance.InstanceName );
				InstanceRemoved();
			}

			return ThreadingUtils.CompletedTask();
		}

		/// <summary>
		/// Called when the owner instance of this options set is deleted
		/// </summary>
		protected abstract void InstanceRemoved();

		/// <summary>
		/// Is this one the default cloud provider
		/// </summary>
		private bool m_isDefault;

		/// <summary>
		/// Is this one the default cloud provider
		/// </summary>
		public bool IsDefault
		{
			get
			{
				return m_isDefault;
			}
			set
			{
				if ( m_isDefault != value )
				{
					m_isDefault = value;

					m_makeDefaultActionItem.Name = m_isDefault ? Strings.LabelOptionsSetCloudIsDefault : Strings.LabelOptionsSetCloudMakeDefault;
					m_makeDefaultActionItem.Enabled = !m_isDefault;

					OnPropertyChanged( new System.ComponentModel.PropertyChangedEventArgs( "IsDefault" ) );
				}
			}
		}

		/// <summary>
		/// Returns the options of this item
		/// </summary>
		/// <returns></returns>
		protected override IDictionary<string, string> GetOptions()
		{
			Dictionary<string, string> ret = new Dictionary<string, string>( GetCustomOptions() );

			ret.Add( "IsDefault", IsDefault.ToString() );

			return ret;
		}

		/// <summary>
		/// Returns the options of this item
		/// </summary>
		/// <returns></returns>
		protected abstract IDictionary<string, string> GetCustomOptions();

		/// <summary>
		/// Sets the options of this item
		/// </summary>
		/// <param name="dictionary"></param>
		protected override async Task SetOptions( IDictionary<string, string> dictionary )
		{
			if ( dictionary.ContainsKey( "IsDefault" ) )
			{
				IsDefault = bool.Parse( dictionary["IsDefault"] );
			}

			await SetCustomOptions( dictionary );
		}

		/// <summary>
		/// Sets the options of this item
		/// </summary>
		/// <returns></returns>
		protected abstract Task SetCustomOptions( IDictionary<string, string> dictionary );

		private void Strings_StaticPropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs e )
		{
			switch ( e.PropertyName )
			{
				case "LabelOptionsSetCloudMakeDefault":
					m_makeDefaultActionItem.Name = Strings.LabelOptionsSetCloudMakeDefault;
					break;
				case "LabelOptionsSetCloudMakeDefaultDescription":
					m_makeDefaultActionItem.Description = Strings.LabelOptionsSetCloudMakeDefaultDescription;
					break;
				case "LabelOptionsSetCloudUnlink":
					m_removeInstanceActionItem.Name = Strings.LabelOptionsSetCloudUnlink;
					break;
				case "LabelOptionsSetCloudUnlinkDescription":
					m_removeInstanceActionItem.Description = Strings.LabelOptionsSetCloudUnlinkDescription;
					break;
			}
		}

	}
}
